<template>
  <div class="home">练习</div>
</template>

<script lang="ts" setup>
import { defineComponent, ref } from "vue";
//这里defineComponent()方法，是为了适配vue里用ts的语法，有类型提示，最重要的是给予了组件正确的参数类型推断。可以去掉不影响
let isOk: boolean = false;

let num: number = 1;

let myChart: string = "jd";

let str: string = `hello ${myChart}`;
/* //void定义空值  智能定义 null 和 undefined
function al(): void {
  alert("hello name isoK");
}
let a: void = undefined; */
console.log(str);

let n1: number[] = [1, 2, 3, 4, 5];
console.log(n1);
n1.push(6);
let n2: [number, string] = [1, "hello"];
console.log(n2);

function e<T>(n1: T): T {
  return n1;
}
const res = e(123);
console.log(res);

function e1<T, U>(n2: [T, U]): [T, U] {
  return [n2[0], n2[1]];
}
const res1 = e1(["str", 123]);

enum o {
  name = 2,
  age,
  sea,
}
console.log(o.age);
console.log(o[2]);

enum obj {
  num = "num",
  age = "age",
  sex = "sex",
}
console.log(obj.num);
const value = "age";
if (value === obj.age) {
  console.log("uu");
}

let obj1 = {
  a: 1,
  b: "2",
};
console.log(obj1.a);

function obj2(obj: object) {
  console.log(obj);
}
obj2({ key: 66 });

interface Iport {
  readonly id: number; //只读
  username: string;
  passwrod: number;
}
let aa: Iport = {
  id: 66,
  username: "admin",
  passwrod: 123456,
};
console.log(aa.username, 79);
// var addnum1: (a: number, b: number) => number = function (
//   a: number,
//   b: number
// ): number {
//   return a + b;
// };
// console.log(addnum1(1, 2));

interface aa1 {
  (a: number, b: number): number;
}

var an1: aa1 = function (a: number, b: number): number {
  return a + b;
};
console.log(an1(2, 3));

function r(a: string, b?: number): string {
  if (b) {
    return `${a},${b}`;
  } else {
    return `${a}`;
  }
}
console.log(r("aa", 11));
console.log("aa");

function num1(a: number, b: number = 1): number {
  return a + b;
}
console.log(num1(2));

function num2(a: number, ...args: number[]): number {
  let total = 0;
  args.forEach((item) => {
    total += item;
  });
  return total;
}
console.log(num2(1, 2));
console.log(num2(1, 2, 3, 4));

//不确定类型的变量到底是哪个类型的时候
let n3: string | number;
n3 = 123;
n3 = "hello";

function add(a: number, b: number) {
  return a + b;
}

function add1(a: number, b: number, c?: number) {
  if (typeof c === "number") {
    return a + b + c;
  } else {
    return a + b;
  }
}

function add2(a: string, b: number): any {
  return `${a},${b}`;
}
console.log(add2("hello", 123));

function add3(): void {
  console.log("没有返回值");
}
add3();
//类

//3.ts提供了三种修饰符：
// public(默认的)： 公有 在类里面、子类类外边都可以访问
// protected：在类里面、子类里面可以访问、在类外部无法访问
// private：在类里面可以访问、子类、类外部没法访问
class person {
  public name1: string; //公有(所有)默认
  constructor(name: string) {
    this.name1 = name;
  }
  add() {
    console.log(`${this.name1}hello`);
  }
}
let p = new person("你好");
console.log(p);
p.add();
class child extends person {
  sex1: string;
  age1: number;

  constructor(name: string, sex: string, age: number) {
    super(name);
    this.sex1 = sex;
    this.age1 = age;
  }
  add1() {
    console.log(this.name1, this.sex1, this.age1);
  }
}
let c = new child("儿子", "男", 18);
console.log(c);
c.add();
c.add1();

class Person1 {
  protected username1: string;
  constructor(name: string) {
    this.username1 = name;
  }
}
class Child extends Person1 {
  constructor(name: string) {
    super(name);
  }
  //子类内部，可以访问protected
  run() {
    return this.username1;
  }
}
let c2 = new Child("李四");
//类外面 ，访问会报错
// console.log(c2.userName1);
//通过子类的函数访问父类受保护的属性是OK的
console.log("protected", c2.run());

//demo3  演示private 	私有的，在当前类的内部使用
class Person3 {
  private userName3: string;
  constructor(name: string) {
    this.userName3 = name;
  }
}
class Child3 extends Person3 {
  constructor(name: string) {
    super(name);
  }
  run() {
    // return this.userName3; //这里会提醒错误
  }
}
let c3 = new Child3("王五");
//通过内部的函数访问父类私有的属性也会报错
console.log("private", c3.run());

//4.3 类与接口，类可以实现(implements)接口
//1.实现单个接口
/* interface Ip1{
    name:string;
    age:number;
}
class Person1 implements Ip1{
    name:string="张三";
    age:number=18;
    show():void{
       console.log(`姓名：${this.name},年龄：${this.age}`);
    }
}

let p1=new Person1()
p1.show() */

interface Ip1 {
  name: string;
  age: number;
}
interface Ip2 {
  change(): void;
}
class Person2 implements Ip1, Ip2 {
  name: string = "张三";
  age: number = 18;
  show(): void {
    console.log(`姓名：${this.name},年龄：${this.age}`);
  }
  //此处如果没有change方法就会报错
  change(): void {
    console.log("接口2里内容");
  }
}

let p2 = new Person2();
p2.show();
</script>
